package com.learn.jdk21.dome;

import org.junit.jupiter.api.Test;

import java.util.concurrent.*;

/**
 * @author caiming01
 * @date 2023/10/23 0:39
 */
public class StructuredTaskDemo {


    @Test
    public void testOldConcurrent() throws ExecutionException, InterruptedException {
        getUserInfo(new GetOrderTask());
    }

    @Test
    public void testOldConcurrentError() throws ExecutionException, InterruptedException {
        getUserInfo(new GetOrderTaskError());
    }

    @Test
    public void testStructuredTaskFailureScope() throws InterruptedException {
        try (StructuredTaskScope.ShutdownOnFailure structuredTaskScope = new StructuredTaskScope.ShutdownOnFailure();) {
            StructuredTaskScope.Subtask<String> userTask = structuredTaskScope.fork(new GetUserTask());
            StructuredTaskScope.Subtask<String> orderTask = structuredTaskScope.fork(new GetOrderTaskError());
            // 阻塞获取用户信息
            String userInfo = userTask.get();
            // 阻塞获取订单信息
            String orderInfo = orderTask.get();
            // 整合数据
            System.out.println(userInfo + orderInfo);
        }
    }

    @Test
    public void testStructuredTaskSuccessScope() {
        try (StructuredTaskScope.ShutdownOnSuccess<String> structuredTaskScope = new StructuredTaskScope.ShutdownOnSuccess<>();) {
            StructuredTaskScope.Subtask<String> userTask = structuredTaskScope.fork(new GetUserTask());
            StructuredTaskScope.Subtask<String> orderTask = structuredTaskScope.fork(new GetOrderTask());
            structuredTaskScope.join();
            // 阻塞获取用户信息
            String userInfo = userTask.get();
            // 阻塞获取订单信息
            String orderInfo = orderTask.get();
            // 整合数据
            System.out.println(userInfo + orderInfo);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    private void getUserInfo(Callable<String> getOrderTask) throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        Future<String> user = executorService.submit(new GetUserTask());
        Future<String> order = executorService.submit(getOrderTask);
        // 阻塞获取用户信息
        String userInfo = user.get();
        // 阻塞获取订单信息
        String orderInfo = order.get();
        // 整合数据
        System.out.println(userInfo + orderInfo);
    }

    static class GetUserTask implements Callable<String> {
        @Override
        public String call() {
            try {
                System.out.println("查询user开始");
                TimeUnit.SECONDS.sleep(3);
                System.out.println("查询user结束");
            } catch (
                    Exception e) {
                throw new RuntimeException(e);
            }
            return "user info";
        }

    }

    static class GetOrderTask implements Callable<String> {
        @Override
        public String call() {
            try {
                System.out.println("查询order开始");
                TimeUnit.SECONDS.sleep(1);
                System.out.println("查询order结束");
            } catch (
                    Exception e) {
                throw new RuntimeException(e);
            }
            return "order info";
        }
    }

    static class GetOrderTaskError implements Callable<String> {
        @Override
        public String call() {
            try {
                System.out.println("查询order开始");
                TimeUnit.SECONDS.sleep(3);
                throw new RuntimeException("系统内部错误");
            } catch (
                    Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
}
